package cn.book.bus.service.impl;


import cn.book.bus.aop.HttpAspect;
import cn.book.bus.domain.Chapter;
import cn.book.bus.domain.ChapterContent;
import cn.book.bus.domain.Fiction;
import cn.book.bus.mapper.ChapterContentMapper;
import cn.book.bus.mapper.ChapterMapper;
import cn.book.bus.service.IFictionService;
import cn.book.bus.service.WriteFictionService;
import cn.book.bus.utils.JsoupUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 小说抓取实现类
 */
@Service
public class WriteFictionServiceImpl implements WriteFictionService {

    private static final Logger log = LoggerFactory.getLogger(HttpAspect.class);

    @Resource
    private IFictionService iFictionService;

    @Resource
    private ChapterContentMapper chapterContentMapper;

    @Resource
    private ChapterMapper chapterMapper;


    /**
     * 抓取小说持久化到mysql数据库
     *
     * @param fictionURL
     */
    @Async
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void insert(String fictionURL) {

        //爬取小说基本信息
        Document doc = JsoupUtil.getDoc(fictionURL);
        Fiction fiction = getFictions(doc);
        if (fiction != null) {
            //查询数据库信息
            QueryWrapper<Fiction> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("fiction_name", fiction.getFictionName());
            Fiction ft = iFictionService.getOne(queryWrapper);
            if (Objects.isNull(ft)) {
                //设置url
                fiction.setFictionUrl(fictionURL);
                iFictionService.save(fiction);
                Elements elements = doc.select("dl dd").get(0).getAllElements();
                log.info("小说章数：" + elements.size());
                //前面12章节重复
                int k = 12;
                //数据库排序
                int sort = 1;
                //前面12章节重复
                int j = elements.size() - 12;
                ChapterContent chapterContent = new ChapterContent();
                for (int i = 0; i < j; i++) {
                    try {
                        String url = elements.get(k).attr("abs:href");
                        Document document = JsoupUtil.getDoc(url);
                        //章节标题
                        String title = document.select("h1").text();
                        //章节内容
                        String text = document.getElementById("article").html();
                        //保存小说内容
                        chapterContentMapper.insert(chapterContent.setContent(text));
                        int id = chapterContent.getId();
                        chapterMapper.insert(new Chapter(url, fiction.getId(), title, sort, id));
                        log.info("抓取小说：" + fiction.getFictionName() + "" + title);
                        sort++;
                        k++;
                    } catch (Exception e) {
                        log.error("抓取小说内容异常" + e);
                    }
                }
                log.info("抓取小说完成");
            } else {
                log.info("这本小说已经保存到数据库");
            }
        } else {
            log.info("小说连接地址错误");
        }
    }

    /**
     * 获取书趣阁小说基本信息
     *
     * @param document
     * @return
     */
    @Override
    public Fiction getFictions(Document document) {
        try {
            //小说基本信息
            String fictionName = document.select("meta[property=og:novel:book_name]").attr("content");
            String brief = document.select("meta[property=og:description]").attr("content");
            String author = document.select("meta[property=og:novel:author]").attr("content");
            String type = document.select("meta[property=og:novel:category]").attr("content");
            String newest = document.select("meta[property=og:novel:latest_chapter_name]").attr("content");
            String state = document.select("meta[property=og:novel:status]").attr("content");
            String img = document.select("#fmimg > img").attr("abs:src");

            //字数
//                String number = JsoupUtil.sub(small.get(0).child(3).text());
            return new Fiction("", img, brief, fictionName, author, type, newest, state, "");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取小说基本信息失败" + e);
        }
        return null;
    }

    /**
     * 获取金庸小说信息
     *
     * @param doc
     */
    public Fiction getJYFictions(Document doc) {
        try {
            String fictionName = Optional.of(JsoupUtil.getTexts(doc, "h1")).filter(list -> !list.isEmpty())
                    .map(list -> list.get(0))
                    .orElse("Default Title");
            String brief = JsoupUtil.getContent(doc, "m-bkcont");
            String author = "";
            String type = "武侠";
            String newest = "";
            // 提取最近更新
            Element updateElement = doc.select("p:contains(最近更新：)").first();
            if (updateElement != null) {
                newest = updateElement.text().replace("最近更新：", "").trim();
            }

            // 提取作者
            Element authorElement = doc.select("p:contains(作者：)").first();
            if (authorElement != null) {
                author = authorElement.text().replace("作者：", "").trim();
            }

            String state = "";
            // 提取状态
            Element statusElement = doc.select("p:contains(状态：)").first();
            if (statusElement != null) {
                state = statusElement.text().replace("状态：", "").trim();
            }
            String img = JsoupUtil.getAttributes(doc, ".book-img img", "src").stream().findFirst().get();
            return new Fiction("", img, brief, fictionName, author, type, newest, state, "");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取小说基本信息失败" + e);
        }
        return null;
    }

    @Override
    public void saveJYFictions(String fictionURL) {
        try {
            Document doc = JsoupUtil.getDoc(fictionURL);
            Fiction fiction = getJYFictions(doc);
            if (fiction != null) {
                //查询数据库信息
                QueryWrapper<Fiction> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("fiction_name", fiction.getFictionName());
                Fiction ft = iFictionService.getOne(queryWrapper);
                if (Objects.isNull(ft)) {
                    //设置url
                    fiction.setFictionUrl(fictionURL);
                    iFictionService.save(fiction);
                    Elements elements = doc.select(".book-list.f-cb ul li a");
                    //数据库排序
                    AtomicInteger sort = new AtomicInteger(1);
                    ChapterContent chapterContent = new ChapterContent();
                    elements.forEach(element -> {
                        String href = element.attr("href");
                        Document document = JsoupUtil.getDoc(href);
                        //章节标题
                        String title = document.select("h1").text();
                        //章节内容
                        String content = JsoupUtil.getContent(document, "m-article-text");
                        // 保存章节内容
                        chapterContentMapper.insert(chapterContent.setContent(content));
                        int id = chapterContent.getId();
                        chapterMapper.insert(new Chapter(href, fiction.getId(), title, sort.get(), id));
                        sort.getAndIncrement();
                    });

                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
